//
//  ZYCompositeImp.m
//  DesignMode
//
//  Created by wangzhipan on 2024/11/6.
//

#import "ZYCompositeImp.h"

static NSString *const kComponentRootName = @"zy_root_component";
static NSString *const kTag = @"ZYComponent";
@interface ZYComponent()
@property (nonatomic, weak, nullable, readwrite) id<IComponent>superComponent;
@property (nonatomic, assign, readwrite) NSUInteger priority;
@property (nonatomic, copy, readwrite) NSString *componentId;
@property (nonatomic, assign, readwrite) BOOL isLoaded;
@property (nonatomic, strong, nullable) NSMutableArray <id<IComponent>>*componentList;

@end

@implementation ZYComponent


#pragma mark - IComponent
- (instancetype)initWithComponentId:(NSString *)componentId priority:(NSUInteger)priority
{
    if (self = [super init]) {
        self.componentId = componentId;
        self.priority = priority;
        self.isLoaded = false;
    }
    return self;
}

- (nonnull instancetype)initWithRootView:(nonnull UIView *)rootView
{
    if (self = [super init]) {
        self.componentId = kComponentRootName;
        self.priority = 0;
        self.isLoaded = false;
        _componentView = rootView;
    }
    return self;
}

- (nullable id<IComponent>)rootComponent
{
    id<IComponent>root = self;
    while (root) {
        if ([root.componentId isEqualToString:kComponentRootName]) {
            return root;
        }
        root = root.superComponent;
    }
    return root;
}
- (void)addComponent:(nonnull id<IComponent>)component
{
    ((ZYComponent *)component).superComponent = self;
    if (self.isLoaded) {    //父组件已经被加到root 树上了，那么再单独加其他组件时，直接触发生命周期方法
        [((id<IComponent, IComponentLifecycle>)component) componentWillLoad];
        [self.componentList addObject:component];
        [((id<IComponent, IComponentLifecycle>)component) componentDidLoad];
    }
    else {
        //父组件未被加入 root树，那么等loader将组件 加入root树时再统一触发组件生命周期
        [self.componentList addObject:component];
    }
}

- (void)removeComponent:(nonnull id<IComponent>)component
{
    if (!component) {
        return;
    }
    NSArray *copyList = self.componentList.copy;
    for (id<IComponent>sub in copyList) {
        if (sub == component) {
            if (component.isLoaded) {
                [((id<IComponent, IComponentLifecycle>)component) componentWillUnload];
                [self.componentList removeObject:component];
                [((id<IComponent, IComponentLifecycle>)component) componentDidUnload];
            }
            else {
                [self.componentList removeObject:sub];
            }
            return;
        }
        else {
            [sub removeComponent:component];
        }
    }
}

- (nullable id<IComponent>)findForComponentId:(nonnull NSString *)componentId
{
    id<IComponent>result = nil;
    if ([self.componentId isEqualToString:componentId]) {
        return self;
    }
    for (id<IComponent>sub in self.componentList) {
        if ([sub.componentId isEqualToString:componentId]) {
            result = sub;
            break;
        }
        else {
            result = [sub findForComponentId:componentId];
        }
    }
    return result;
}

#pragma mark - IComponentUI
- (void)layoutInSuperComponentView:(UIView *)superView
{
    self.componentView.frame = superView.bounds;
}

- (BOOL)isLazyLoadUI
{
    return false;
}

- (void)loadComponentViewIfNeed:(nullable void(^)( UIView *componentView))completed
{
    if (!self.componentView) {
        self.componentView = [self lazyLoadView];
    }
    
    if (self.superComponent && self.componentView && self.componentView.superview == nil) {
        id<IComponent, IComponentUI>superComponent = (id<IComponent, IComponentUI>)self.superComponent;
        [superComponent loadComponentViewIfNeed:nil];
        [superComponent.componentView addSubview:self.componentView];
        [self layoutInSuperComponentView:superComponent.componentView];
        NSLog(@"%@, loadComponentView, componentId: %@", kTag, self.componentId);
    }
    completed ? completed(self.componentView) : nil;
}

- (nullable UIView *)lazyLoadView 
{
    return nil;
}



#pragma mark - IComponentLifecycle
- (void)componentWillLoad
{
    NSLog(@"%@, %s, componentId: %@", kTag, __func__, self.componentId);
    if (_componentList.count) {
        for (id<IComponent, IComponentLifecycle>sub in self.componentList) {
            [sub componentWillLoad];
        }
    }
}

- (void)componentDidLoad
{
    NSLog(@"%@, %s, componentId: %@", kTag, __func__, self.componentId);
    self.isLoaded = true;
    //非懒加载的view 添加到主视图上
    if (!self.isLazyLoadUI) {
        [self loadComponentViewIfNeed:nil];
    }
    if (_componentList.count) {
        for (id<IComponent, IComponentLifecycle>sub in self.componentList) {
            [sub componentDidLoad];
        }
    }
}

- (void)componentWillUnload
{
    NSLog(@"%@, %s, componentId: %@", kTag, __func__, self.componentId);
    
    if (_componentList.count) {
        for (id<IComponent, IComponentLifecycle>sub in self.componentList) {
            [sub componentWillUnload];
        }
    }
}
- (void)componentDidUnload
{
    NSLog(@"%@, %s, componentId: %@", kTag, __func__, self.componentId);
    if (_componentList.count) {
        for (id<IComponent, IComponentLifecycle>sub in self.componentList) {
            [sub componentDidUnload];
        }
    }
    self.isLoaded = false;
    [_componentView removeFromSuperview];
    self.superComponent = nil;
    [self.componentList removeAllObjects];
}


#pragma mark - getter && setter
- (NSMutableArray<id<IComponent>> *)componentList
{
    if (!_componentList) {
        _componentList = [NSMutableArray arrayWithCapacity:3];
    }
    return _componentList;
}
@end
